* Package
** Initialize package
#+BEGIN_SRC emacs-lisp
  (require 'package)
  (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
  (package-initialize)
#+END_SRC
** Function to install packages
#+BEGIN_SRC emacs-lisp
  (defun pacins(name)
    (unless (package-installed-p name)
      (package-install name)))
#+END_SRC
** Install use-package
#+BEGIN_SRC emacs-lisp
  (pacins 'use-package)
  (require 'use-package)
#+END_SRC
* General
Disable auto save
#+BEGIN_SRC emacs-lisp
  (setq auto-save-default nil)
  (setq make-backup-files nil)
#+END_SRC
Line number mode in prog-mode
#+BEGIN_SRC emacs-lisp
  (global-linum-mode)
  (setq nlinum-format " %d ")
#+END_SRC
Enabled electric-pairs moded in prog mode
#+BEGIN_SRC emacs-lisp
  (add-hook 'prog-mode-hook 'electric-pair-mode)
#+END_SRC
No pagedup/down when scrolling
#+BEGIN_SRC emacs-lisp
  (setq scroll-conservatively 100)
#+END_SRC
Tab width
#+BEGIN_SRC emacs-lisp
  (setq-default indent-tabs-mode nil)
  (setq-default tab-width 2)
  (setq-default python-indent-offset tab-width)
#+END_SRC
Enable visual line mode
#+BEGIN_SRC emacs-lisp
  (global-visual-line-mode 1)
#+END_SRC
Kill greeting buffer
#+BEGIN_SRC emacs-lisp
  (setq initial-buffer-choice t)
#+END_SRC

* Reload config
#+BEGIN_SRC emacs-lisp
  (defun reload-config()
    (interactive)
    (org-babel-load-file (concat user-emacs-directory "config.org")))
#+END_SRC
* Modeline
#+BEGIN_SRC emacs-lisp
  (use-package doom-modeline
    :ensure t
    :config
    (setq doom-modeline-icon nil)
    (doom-modeline-mode 1))
#+END_SRC
* Ivy
Install helm
#+BEGIN_SRC emacs-lisp
  (use-package ivy
    :ensure t
    :config
    (ivy-mode))
#+END_SRC
* Swiper
#+BEGIN_SRC emacs-lisp
  (use-package swiper
    :ensure t)
#+END_SRC
* Avy
#+BEGIN_SRC emacs-lisp
  (use-package avy
    :ensure t)
#+END_SRC
* Company
#+BEGIN_SRC emacs-lisp
  (use-package company
    :ensure t
    :config
    (add-hook 'prog-mode-hook 'company-mode))
#+END_SRC
* Lua
#+BEGIN_SRC emacs-lisp
  (use-package lua-mode
    :ensure t
    :config
    (setq lua-indent-level tab-width))
#+END_SRC
* C++/C
#+BEGIN_SRC emacs-lisp
  (use-package irony
    :ensure t
    :config
    (add-hook 'c++-mode-hook 'irony-mode)
    (add-hook 'c-mode-hook 'irony-mode)
    (add-hook 'objc-mode-hook 'irony-mode)
    (add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options))

  (use-package company-irony
    :ensure t
    :config
    (eval-after-load 'company
      '(add-to-list 'company-backends 'company-irony)))

  (use-package company-irony-c-headers
    :ensure t
    :config
    (eval-after-load 'company
      '(add-to-list
        'company-backends '(company-irony-c-headers company-irony))))
#+END_SRC
* Flycheck
#+BEGIN_SRC emacs-lisp
  (use-package flycheck
    :ensure t
    :config
    (global-flycheck-mode))
#+END_SRC
* Which-key
#+BEGIN_SRC emacs-lisp
  (use-package which-key
    :ensure t
    :config
    (which-key-mode 1))
#+END_SRC
* Beacon
#+BEGIN_SRC emacs-lisp
  (use-package beacon
    :ensure t
    :config
    (beacon-mode))
#+END_SRC
* Highlight parentheses
#+BEGIN_SRC emacs-lisp
  (use-package highlight-parentheses
    :ensure t
    :config
    (global-highlight-parentheses-mode 1))
#+END_SRC
* Origami
#+BEGIN_SRC emacs-lisp
  (use-package origami
    :ensure t
    :config
    (global-origami-mode))
#+END_SRC
* Eshell
** Toggle eshell
This function runs eshell when not inside it, when run inside eshell, it kills the buffer
#+BEGIN_SRC emacs-lisp
  (defun toggle-eshell()
    (interactive)
    (if (string= (buffer-name) "*eshell*")
	(switch-to-prev-buffer)
      (eshell)))
#+END_SRC
* Multiple Cursors
#+BEGIN_SRC emacs-lisp
  (use-package multiple-cursors
    :ensure t)

  (use-package mc-extras
    :ensure t)

  (setq mc/always-run-for-all t)
#+END_SRC
* Dired
** Dired subtree
#+BEGIN_SRC emacs-lisp
  (use-package dired-subtree
    :ensure t)
#+END_SRC
* Functions
** Mass define keys
#+BEGIN_SRC emacs-lisp
  (defun mass-define-key(keymap keys)
    (dolist (key keys)
      (define-key keymap (kbd (car key)) (cdr key))))
#+END_SRC
** Do nothing
#+BEGIN_SRC emacs-lisp
  (defun do-nothing() (interactive))
#+END_SRC
** edit commands
#+BEGIN_SRC emacs-lisp
  (defun copy-whole-line-as-kill()
    (interactive)
    (save-excursion
      (beginning-of-line)
      (set-mark (point))
      (end-of-line)
      (copy-region-as-kill (region-beginning) (region-end))
      (pop-mark)))

  (defun newline-no-disturb()
    (interactive)
    (end-of-line)
    (newline-and-indent))

  (defun edit/insert-before()
    (interactive)
    (modal/into-insert-mode))

  (defun edit/insert-after()
    (interactive)
    (forward-char)
    (modal/into-insert-mode))

  (defun edit/insert-beginning-of-line()
    (interactive)
    (beginning-of-line-text)
    (modal/into-insert-mode))

  (defun edit/insert-end-of-line()
    (interactive)
    (end-of-line)
    (modal/into-insert-mode))

  (defun edit/insert-newline()
    (interactive)
    (newline-no-disturb)
    (modal/into-insert-mode))

  (defun edit/yank-beg-newline()
    (interactive)
    (newline-no-disturb)
    (beginning-of-line)
    (yank))

  (defun edit/replace-char()
    (interactive)
    (delete-char 1)
    (modal/into-insert-mode))

  (defun edit/replace-line()
    (interactive)
    (kill-whole-line)
    (newline)
    (previous-line)
    (modal/into-insert-mode))

  (defun edit/set-region()
    (interactive)
    (set-mark (point))
    (modal/into-region-mode))

  (defun edit/set-region-line()
    (interactive)
    (beginning-of-line)
    (edit/set-region)
    (next-line)
    (beginning-of-line))

  (defun edit/kill-region()
    (interactive)
    (kill-region (region-beginning) (region-end))
    (modal/into-normal-mode))

  (defun edit/surround-region(&optional char1 char2)
    (interactive)
    (when (called-interactively-p 'any)
      (setq char1 (read-from-minibuffer "beginning text: "))
      (setq char2 (read-from-minibuffer "ending text: ")))  
    (save-excursion
      (goto-char (region-beginning))
      (insert char1))
    (save-excursion
      (goto-char (region-end))
      (insert char2))
    (modal/into-normal-mode))

  (defun edit/copy-region-as-kill()
    (interactive)
    (copy-region-as-kill (region-beginning) (region-end))
    (modal/into-normal-mode))

  (defun edit/yank-replace-region()
    (interactive)
    (delete-region (region-beginning) (region-end))
    (yank)
    (modal/into-normal-mode))

  (defun edit/replace-region()
    (interactive)
    (kill-region (region-beginning) (region-end))
    (modal/into-normal-mode)
    (modal/into-insert-mode))

  (defun edit/set-rectangle()
    (interactive)
    (rectangle-mark-mode 1)
    (modal/into-rectangle-mode))

  (defun edit/kill-rectangle()
    (interactive)
    (kill-rectangle (region-beginning) (region-end))
    (modal/into-normal-mode))

  (defun edit/copy-rectangle-as-kill()
    (interactive)
    (copy-rectangle-as-kill (region-beginning) (region-end))
    (modal/into-normal-mode))

  (defun edit/replace-rectangle()
    (interactive)
    (replace-rectangle (region-beginning) (region-end) (read-from-minibuffer "Text: "))
    (modal/into-normal-mode))

  (defun edit/yank-replace-rectangle()
    (interactive)
    (replace-rectangle (region-beginning) (region-end) (current-kill 0))
    (modal/into-normal-mode))

  (defun edit/kill-inside-word()
    (interactive)
    (forward-char)
    (backward-word)
    (kill-word nil))

  (defun motion/inside-word()
    (interactive)
    (forward-char)
    (backward-word)
    (set-mark (point))
    (forward-word)
    (modal/into-region-mode))

  (defun motion/inside-surround(char1 char2)
    (interactive)
    (forward-char)
    (search-backward char1)
    (forward-char)
    (set-mark (point))
    (search-forward char2)
    (backward-char)
    (modal/into-region-mode))    

  (defun mark/insert-mark()
    (interactive)
    (insert "{[><]}"))

  (defun mark/next-mark()
    (interactive)
    (search-forward "{[><]}")
    (search-backward "{")
    (set-mark (point))
    (search-forward "}")
    (delete-region (region-beginning) (region-end))
    (modal/into-insert-mode)
    )
#+END_SRC
** Zoom in and out
#+BEGIN_SRC emacs-lisp
  (defadvice text-scale-increase (after text-scale-after activate)
    (set-window-margins (selected-window) 1 1))
  (defadvice text-scale-decrease (after text-scale-after activate)
    (set-window-margins (selected-window) 1 1))
  (defadvice text-scale-set (after text-scale-after activate)
    (set-window-margins (selected-window) 1 1))
#+END_SRC
* Modal editing
Make keymap that does nothing when self inserting keys are pressed
#+BEGIN_SRC emacs-lisp
  (setq self-inserting-keys '("`" "1" "2" "3" "4" "5" "6" "7" "8" "9" "0" "-" "=" "q" "w" "e" "r" "t" "y" "u" "i" "o" "p" "[" "]" "\\" "a" "s" "d" "f" "g" "h" "j" "k" "l" ";" "'" "z" "x" "c" "v" "b" "n" "m" "," "." "/" "~" "!" "@" "#" "$" "%" "^" "&" "*" "(" ")" "_" "+" "Q" "W" "E" "R" "T" "Y" "U" "I" "O" "P" "{" "}" "|" "A" "S" "D" "F" "G" "H" "J" "K" "L" ":" "\"" "Z" "X" "C" "V" "B" "N" "M" "<" ">" "?" "<return>" "<backspace>" "<SPC>"))

  (defun make-no-insert-keymap()
    (setq result (make-sparse-keymap))
    (dolist (key self-inserting-keys)
      (define-key result (kbd key) 'do-nothing))
    result)
#+END_SRC
* Keybindings
#+BEGIN_SRC emacs-lisp
  (setq modal/normal-map (make-no-insert-keymap))
  (setq modal/region-map (make-no-insert-keymap))
  (setq modal/rectangle-map (make-no-insert-keymap))
  (setq modal/insert-map (make-sparse-keymap))
  (setq modal/emacs-map (make-sparse-keymap))  

  (setq kbd/normal-bare-mode
  '(
    ("n" . next-line)
    ("N" . (lambda() (interactive) (next-line 10)))	
    ("C-n" . scroll-up)
    ("p" . previous-line)
    ("P" . (lambda() (interactive) (previous-line 10)))
    ("C-p" . scroll-down)
    ("o" . forward-char)
    ("O" . forward-word)
    ("b" . backward-char)
    ("B" . backward-word)
    ("q" . beginning-of-line)
    ("e" . end-of-line)
    ("f" . swiper)
    ("@" . universal-argument)		
    ))

  (setq kbd/normal-mode
  '(
    ("n" . next-line)
    ("N" . (lambda() (interactive) (next-line 10)))	
    ("C-n" . scroll-up)
    ("p" . previous-line)
    ("P" . (lambda() (interactive) (previous-line 10)))
    ("C-p" . scroll-down)
    ("o" . forward-char)
    ("O" . forward-word)
    ("b" . backward-char)
    ("B" . backward-word)
    ("a" . edit/insert-before)	  
    ("A" . edit/insert-beginning-of-line)
    ("d" . edit/insert-after)
    ("D" . edit/insert-end-of-line)
    ("q" . beginning-of-line)
    ("e" . end-of-line)
    ("J" . copy-whole-line-as-kill)
    ("K" . kill-whole-line)
    ("k" . delete-char)
    ("l" . yank)
    ("f" . swiper)
    ("L" . edit/yank-beg-newline)
    ("h" . edit/replace-char)
    ("H" . edit/replace-line)
    ("s" . newline-no-disturb)
    ("S" . edit/insert-newline)
    ("/" . undo)
    ("r" . edit/set-region)	  
    ("R" . edit/set-region-line)
    ("C-r" . edit/set-rectangle)
    ("TAB" . origami-toggle-node)

    ("m" . mark/next-mark)
    ("M" . mark/insert-mark)

    ("x" . nil)
    ("x e b" . eval-buffer)
    ("x e r" . eval-region)
    ("x e e" . eval-expression)	  
    ("x R" . reload-config)
    ("x RET" . toggle-eshell)
    ("x s" . save-buffer)

    ("i" . nil)
    ("i w" . motion/inside-word)
    ("i (" . (lambda () (interactive) (motion/inside-surround "(" ")")))
    ("i [" . (lambda () (interactive) (motion/inside-surround "[" "]")))
    ("i {" . (lambda () (interactive) (motion/inside-surround "{" "}")))	  	  
    ("i \"" . (lambda () (interactive) (motion/inside-surround "\"" "\"")))
    ("i '" . (lambda () (interactive) (motion/inside-surround "'" "'")))

    ("g" . nil)
    ("g l" . goto-line)
    ("g c" . avy-goto-char)

    ("c" . nil)
    ("c a n" . mc/mark-all-below)
    ("c a p" . mc/mark-all-above)
    ("c a r" . mc/mark-all-in-region)
    ("c a a" . mc/mark-all-like-this)
    ("c n n" . mc/mark-next-like-this)  

    ("@" . universal-argument)		
    ))

  (setq kbd/region-mode
  '(
    ("r" . do-nothing)	  
    ("r" . do-nothing)
    ("C-r" . do-nothing)	
    ("j" . edit/copy-region-as-kill)
    ("k" . edit/kill-region)
    ("l" . edit/yank-replace-region)
    ("h" . edit/replace-region)
    ("i" . nil)
    ("i i" . edit/surround-region)	  
    ("i (" . (lambda () (interactive) (edit/surround-region "(" ")")))
    ("i [" . (lambda () (interactive) (edit/surround-region "[" "]")))
    ("i {" . (lambda () (interactive) (edit/surround-region "{" "}")))	  	  
    ("i \"" . (lambda () (interactive) (edit/surround-region "\"" "\"")))
    ("i '" . (lambda () (interactive) (edit/surround-region "'" "'")))
    ("c a n" . mc/mark-all-below)
    ("c a p" . mc/mark-all-above)
    ("c a r" . mc/mark-all-in-region)
    ("c a a" . mc/mark-all-like-this)
    ("c n n" . mc/mark-next-like-this)
    ("C-g" . modal/into-normal-mode)
    ("M-q" . modal/into-normal-mode)
    ("TAB" . indent-region)
    ))

  (setq kbd/rectangle-mode
  '(
    ("j" . edit/copy-rectangle-as-kill)
    ("k" . edit/kill-rectangle)
    ("l" . edit/yank-replace-rectangle)
    ("h" . edit/replace-rectangle)
    ("c c" . mc/rect-rectangle-to-multiple-cursors)
    ))

  (setq kbd/emacs-mode
  '(
    ("C-x RET" . toggle-eshell)
    ("C-q k" . delete-window)
    ("C-q p" . (lambda() (interactive) (other-window -1)))
    ("C-q n" . (lambda() (interactive) (other-window 1)))
    ("C-q C-k" . delete-window)
    ("C-q C-p" . (lambda() (interactive) (other-window -1)))
    ("C-q C-n" . (lambda() (interactive) (other-window 1)))
    ("C-q N" . split-window-vertically)
    ("C-q P" . split-window-vertically)
    ("C-q O" . split-window-horizontally)
    ("C-q B" . split-window-horizontally)
    ("M-q" . modal/into-normal-mode)
    ("M-e" . modal/into-emacs-mode)
    ))



  (mass-define-key modal/emacs-map kbd/emacs-mode)
  (mass-define-key modal/normal-map kbd/emacs-mode)
  (mass-define-key modal/normal-map kbd/normal-mode)
  (mass-define-key modal/region-map kbd/normal-mode)
  (mass-define-key modal/region-map kbd/region-mode)
  (mass-define-key modal/rectangle-map kbd/normal-mode)
  (mass-define-key modal/rectangle-map kbd/region-mode)
  (mass-define-key modal/rectangle-map kbd/rectangle-mode)

  (define-key modal/insert-map (kbd "M-q") 'modal/into-normal-mode)
  (define-key modal/normal-map (kbd "M-q") 'do-nothing)

  (setq kbd/company-active
        '(
          ("C-n" . company-select-next)
          ("C-p" . company-select-previous)
          ("RET" . do-nothing)
          ("<return>" . do-nothing)
          ("TAB" . company-complete-selection)
          ("<tab>" . company-complete-selection)
          ))

  (setq kbd/dired-mode
        '(
          ("TAB" . dired-subtree-toggle)
          ("<tab>" . dired-subtree-toggle)
          ("m" . dired-mark)
          ("M" . dired-unmark)
          ("C-m" . dired-unmark-all-marks)
          ("k" . dired-flag-file-deletion)
          ("K" . dired-do-flagged-delete)        
          ("j" . dired-copy-file)
          ("RET" . dired-find-file)
          ("C-m" . dired-find-file)
                  ))

  (setq kbd/eshell-mode
        '(
          ("C-n" . eshell-next-input)
          ("C-p" . eshell-previous-input)        
          ))

  (mass-define-key dired-mode-map kbd/normal-bare-mode)
  (mass-define-key dired-mode-map kbd/dired-mode)
  (mass-define-key company-active-map kbd/company-active)
  (add-hook 'eshell-mode-hook (lambda()
        (interactive)
        (mass-define-key eshell-mode-map kbd/eshell-mode)
        ))

#+END_SRC
* Modes
#+BEGIN_SRC emacs-lisp
    (setq-default current-mode-local "EMS")

    (defun modal/clear()
      (interactive)
      (modal/normal-mode 0)
      (modal/insert-mode 0)
      (modal/region-mode 0)
      (modal/rectangle-mode 0)
      (modal/emacs-mode 0))

    (define-minor-mode modal/init-mode "Global-mode" t " Modal" nil
      (if modal/init-mode
          (progn
            (if (not (or 
                      (minibufferp)
                      (equal major-mode 'dired-mode)
                      (equal major-mode 'eshell-mode)                    
                      ))
                (modal/into-normal-mode)
              (modal/into-emacs-mode)))))

    (define-global-minor-mode modal/global-mode modal/init-mode modal/init-mode)
    (add-hook 'after-init-hook (lambda() (interactive) (modal/global-mode 1)))

    (define-minor-mode modal/normal-mode "Normal-mode" nil " [Nor]" modal/normal-map
      (if modal/normal-mode
          (progn
            (pop-mark)
            (rectangle-mark-mode 0)
            (setq current-mode-local "NOR")        
            (setq cursor-type 'box))))

    (define-minor-mode modal/region-mode "Region-mode" nil " [Reg]" modal/region-map
      (if modal/region-mode
          (progn
            (setq current-mode-local "REG")        
            (setq cursor-type 'box))))

    (define-minor-mode modal/rectangle-mode "Rectangle-mode" nil " [Rect]" modal/rectangle-map
      (if modal/rectangle-mode
          (progn
            (setq current-mode-local "REC")        
            (setq cursor-type 'box))))

    (define-minor-mode modal/insert-mode "Insert-mode" nil " [Ins]" modal/insert-map
      (if modal/insert-mode
          (progn
            (setq current-mode-local "INS")
            (setq cursor-type 'bar))))

    (define-minor-mode modal/emacs-mode "emacs-mode" nil " [Ems]" modal/emacs-map
      (if modal/emacs-mode
          (progn
            (setq current-mode-local "EMS")        
            (setq cursor-type 'box))))

    (defun modal/into-normal-mode()
      (interactive)
      (modal/clear)
      (modal/normal-mode 1))

    (defun modal/into-region-mode()
      (interactive)
      (modal/clear)
      (modal/region-mode 1))

    (defun modal/into-rectangle-mode()
      (interactive)
      (modal/clear)
      (modal/rectangle-mode 1))

    (defun modal/into-insert-mode()
      (interactive)
      (modal/clear)
      (modal/insert-mode 1))

    (defun modal/into-emacs-mode()
      (interactive)
      (modal/clear)
      (modal/emacs-mode 1))

#+END_SRC
* Theme
** UI
Disable menu bar
#+BEGIN_SRC emacs-lisp
  (menu-bar-mode -1)
#+END_SRC
Disable tool bar
#+BEGIN_SRC emacs-lisp
  (tool-bar-mode -1)
#+END_SRC
Disable scroll bar
#+BEGIN_SRC emacs-lisp
  (if (display-graphic-p)
      (scroll-bar-mode -1))
#+END_SRC
Set font
#+BEGIN_SRC emacs-lisp
  (setq fonts-options '("Inconsolata"))
  (setq selected-font "")

  (dolist (font-name fonts-options)
    (when (find-font (font-spec :name font-name))
    (setq selected-font font-name)))
  (if (display-graphic-p)
    (set-face-attribute 'default nil :family selected-font :height 128))

#+END_SRC
Highligh current line
#+BEGIN_SRC emacs-lisp
  (if (display-graphic-p) (global-hl-line-mode 1))
#+END_SRC
** Colorscheme
#+BEGIN_SRC emacs-lisp
  (pacins 'doom-themes)
  (setq theme/name 'doom-one)
  (setq theme/custom-theme (and (not (eq system-type 'windows-nt)) t))
  (if (display-graphic-p)
      (load-theme theme/name t)
    (disable-theme theme/name))
#+END_SRC
** Custom colors
#+BEGIN_SRC emacs-lisp
  (setq colors/bg-main "#202020")
  (setq colors/bg-light "#252525")
  (setq colors/bg-lighter "#404040")
  (setq colors/bg-dark "#181818")
  (setq colors/fg-main "#FFFFFF")

  (if (eq colors/bg-main "^color-bg^")
      (setq theme/custom-theme nil))

  (if (and (display-graphic-p) theme/custom-theme) (progn

  (set-face-attribute 'default nil
                      :background colors/bg-main
                      :foreground colors/fg-main)

  (set-face-attribute 'region nil
                      :background colors/bg-lighter)

  (set-face-attribute 'mode-line nil
                      :background colors/bg-dark
                      )

  (set-face-attribute 'mode-line-inactive nil
                      :background colors/bg-main
                      )


  (set-face-attribute 'org-block nil
                      :background colors/bg-main
                      :foreground colors/fg-main)

  (set-face-attribute 'hl-line nil
                      :background colors/bg-light)

  (set-face-attribute 'cursor nil
                      :background colors/fg-main)

  (setq doom-modeline-height 30)

  ))
#+END_SRC

